<?php

/***
 * Class CW_CacheClass is a static class that handles all aspects of managing cached files and cached content.
 ***/
class CW_CacheClass {

   /**
	* Denotes the lifespan of a cached file
	* @access Public
	* @var Integer
	*/
	const CACHE_TIME_TO_LIVE = 300; // 5 minutes


   /**
	* The extension to give cached files
	* @access Public
	* @var String
	*/
	const CACHE_EXTENSION = 'cache';


   // ! Executor Method

   /**
	* Removes all cached files within $path.
	*
	* @param String $path File path to clean up
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return Boolean
	*/
	static public function releaseAllCache($path)
	{
		if(false == is_dir($path))
		{
			return false;
		}

		foreach(glob($path . DIRECTORY_SEPARATOR . '*.' . self::CACHE_EXTENSION) as $cached)
		{
			self::releaseSingleCache($cached);
		}

		return true;
	}


   // ! Accessor Method

   /**
	* Determines whether a file is cached or not.
	*
	* @param String $file Absolute path to file
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return Boolean
	*/
	static public function isFileCached($file)
	{
		return end(explode('.', $file)) == self::CACHE_EXTENSION;
	}


   // ! Accessor Method

   /**
	* Determines whether a cached file is expired.
	*
	* @param String $file Absolute path to file
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return Boolean
	*/
	static public function isCacheExpired($file)
	{
		if((time() - filemtime($file)) >= self::CACHE_TIME_TO_LIVE)
		{
			return true;
		}

		return false;
	}


   // ! Executor Method

   /**
	* Deletes a single cached file.
	*
	* @param String $file Absolute path to file
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return Boolean
	*/
	static public function releaseSingleCache($file)
	{
		return self::isFileCached($file) ? @unlink($file) : false;
	}


   // ! Executor Method

   /**
	* Updates the 'last modified' time of a cached file.
	*
	* @param String $controller Name of the default controller
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return True
	*/
	static public function touchCache($file)
	{
		return self::isFileCached($file) ? touch($file) : false;
	}


   // ! Executor Method

   /**
	* Simply creates a cache id
	*
	* @param String $file Name of the file
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return String
	*/
	static public function getCacheId($file)
	{
		return md5($file);
	}


   // ! Executor Method

   /**
	* Decompresses cached content.
	*
	* @param String $content Content to decompress
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return String
	*/
	static public function decompressContent($content)
	{
		if(function_exists('gzcompress'))
		{
			return $content = gzuncompress(base64_decode($content));
		}

		return base64_decode($content);
	}


   // ! Executor Method

   /**
	* Compresses cached content.
	*
	* @param String $content Content to compress
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return String
	*/
	static public function compressContent($content)
	{
		if(function_exists('gzcompress'))
		{
			return $content = base64_encode(gzcompress($content));
		}

		return base64_encode($content);
	}


   // ! Executor Method

   /**
	* First checks if the specified save path is valid. Then creates
	* a cache id and compresses the content.
	*
	* @param String $path Absolute path to save cached content
	* @param String $name Name of the cached file.
	* @param String $content Content to cache
	* @param Boolean $compress Turns content compression on or off
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return Mixed
	*/
	static public function storeCache($path, $name, $content, $compress = false)
	{
		if(false == is_dir($path))
		{
			return false;
		}

		if(false == MutexClass::processFileLock($path, $name, self::CACHE_TIME_TO_LIVE))
		{
			return false;
		}

		if(false == file_put_contents(self::getFullCachePath($path, $name), ($compress ? self::compressContent($content) : base64_encode($content))))
		{
			return false;
		}

		MutexClass::unlockFile(MutexClass::getFullLockPath($path, $name));

		return true;
	}


   // ! Executor Method

   /**
	* Returns the full path of a cache file
	*
	* @param String $path Absolute path to save cached content
	* @param String $name Name of the cached file.
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return String
	*/
	static public function getFullCachePath($path, $file)
	{
		return preg_replace('#[/|\\\]+$#', '', $path) . DIRECTORY_SEPARATOR . self::getCacheId($name) . '.' . self::CACHE_EXTENSION;
	}


   // ! Accessor Method

   /**
	* Returns content from a cached file.
	*
	* @param String $path Absolute path to save cached content
	* @param String $name Name of the cached file.
	* @param Boolean $compressed Will decompress cached content if needed
	* @author Daniel Wilhelm II Murdoch <wilhelm.murdoch@gmail.com>
	* @since v 1.0.0
	* @access Public
	* @return Mixed
	*/
	static public function getCache($path, $name, $compressed = false)
	{
		if(false == is_dir($path))
		{
			return false;
		}

		$full_cache_path = self::getFullCachePath($path, $name);

		if(false == file_exists($full_cache_path))
		{
			return false;
		}

		if($compressed)
		{
			return self::decompressContent(file_get_contents($full_cache_path));
		}

		return base64_decode(file_get_contents($full_cache_path));
	}
}

?>